package com.scyshkj.university.wechat.utils;

import org.apache.commons.lang.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * 日期工具类
 * Created by 唐旭 on 2015/11/3.
 */
public abstract class DateUtils {

    /**
     * Default time format :  yyyy-MM-dd HH:mm:ss
     */
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * Date include week
     */
    public static final String DATE_WEEK_FORMAT = "yyyy-MM-dd (E)";

    /**
     * Time format :  yyyy-MM-dd HH:mm
     */
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    public static final String TIME_FORMAT = "HH:mm";

    /**
     * Default date format
     */
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    /**
     * Default month format
     */
    public static final String MONTH_FORMAT = "yyyy-MM";

    /**
     * Default only month format
     */
    public static final String MONTH_ONLY_FORMAT = "MM";

    /**
     * Default day format
     */
    public static final String DAY_FORMAT = "dd";
    /**
     * year format
     */
    public static final String YEAR_FORMAT = "yyyy";

    public static final String YYYYMMDDHH = "yyyy-MM-dd HH";
    public static final String YYYYMMDDHH_PATTERN = "^[0-9]{4}\\-[0-9]{2}\\-[0-9]{2} [0-9]{1,2}$";

    public static final long DAY_MILLISECONDS = (1000l * 60 * 60 * 24);

    //Date pattern,  demo:  2013-09-11
    public static final String DATE_PATTERN = "^[0-9]{4}\\-[0-9]{2}\\-[0-9]{2}$";

    //Time pattern,  demo:  12:30
    public static final String TIME_PATTERN = "^[0-9]{1,2}:[0-9]{2}$";

    //Time pattern,  demo:  2013-09-11 12:30
    public static final String DATE_TIME_PATTERN = "^[0-9]{4}\\-[0-9]{2}\\-[0-9]{2} [0-9]{1,2}:[0-9]{2}$";

    //Default one year days: 365
    public static final long DAYS_OF_YEAR = 365;

    //Default one month days: 30
    public static final long DAYS_OF_MONTH = 30;

    public static boolean isDate(String dateAsText) {
        return StringUtils.isNotEmpty(dateAsText) && dateAsText.matches(DATE_PATTERN);
    }

    public static boolean isDate(String dateAsText, String format) {
        return StringUtils.isNotEmpty(dateAsText) && dateAsText.matches(format);
    }

    public static boolean isTime(String timeAsText) {
        return StringUtils.isNotEmpty(timeAsText) && timeAsText.matches(TIME_PATTERN);
    }

    /**
     * 判断字符串是否为 日期时间格式, 如: 2014-02-11 12:23
     *
     * @param dateTimeAsText dateTimeAsText
     * @return True it is available, otherwise false
     */
    public static boolean isDateTime(String dateTimeAsText) {
        return StringUtils.isNotEmpty(dateTimeAsText) && dateTimeAsText.matches(DATE_TIME_PATTERN);
    }

    public static Date now() {
        return new Date();
    }

    public static String toDateText(Date date) {
        return toDateText(date, DATE_FORMAT);
    }

    public static String toDateText(Date date, String pattern) {
        if (date == null || pattern == null) {
            return null;
        }
        SimpleDateFormat dateFormat = newDateFormat(pattern);
        return dateFormat.format(date);
    }

    public static Date getDate(String dateText) {
        return getDate(dateText, DATE_FORMAT);
    }


    public static Date getDate(String dateText, String pattern) {
        SimpleDateFormat dateFormat = newDateFormat(pattern);
        try {
            return dateFormat.parse(dateText);
        } catch (ParseException e) {
            throw new IllegalStateException("Parse date from [" + dateText + "," + pattern + "] failed", e);
        }
    }

    //Create new  SimpleDateFormat
    private static SimpleDateFormat newDateFormat(String pattern) {
        return new SimpleDateFormat(pattern, Locale.SIMPLIFIED_CHINESE);
    }

    public static String toDateTime(Date date) {
        return toDateText(date, DATE_TIME_FORMAT);
    }


    /**
     * Return current year.
     *
     * @return Current year
     */
    public static int currentYear() {
        return calendar().get(Calendar.YEAR);
    }

    /**
     * Return current month, start by 1 (not 0)
     *
     * @return Current month
     */
    public static int currentMonth() {
        return calendar().get(Calendar.MONTH) + 1;
    }


    public static Calendar calendar() {
        return Calendar.getInstance();
    }

    /**
     * 判断是否为周末(周六或周日)
     *
     * @param date Date
     * @return True is weekend, otherwise false
     */
    public static boolean isWeekend(Date date) {
        if (date == null) {
            return false;
        }
        Calendar calendar = calendar();
        calendar.setTime(date);

        final int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        return dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.SATURDAY;
    }


    /**
     * 判断 两个日期是否相等, 只比较 年月日, 不比较时分秒
     * 即只要日期相等就相等.
     * 如 2014-01-01 12:23:34  与 2014-01-01 11:20:30 是相等
     *
     * @param date1 date1
     * @param date2 date2
     * @return True is equal, otherwise false
     */
    public static boolean equalDate(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return false;
        }
        final String date1Text = toDateText(date1);
        final String date2Text = toDateText(date2);
        return date1Text.equals(date2Text);
    }


    /**
     * Get tow dates period as days,
     * return -1 if the start or end is null
     *
     * @param start Start date
     * @param end   End date
     * @return Period as days or -1
     */
    public static long periodAsDays(Date start, Date end) {
        if (start == null || end == null) {
            return -1;
        }
        Date start1 = org.apache.commons.lang.time.DateUtils.truncate(start, Calendar.DAY_OF_MONTH);
        Date end1 = org.apache.commons.lang.time.DateUtils.truncate(end, Calendar.DAY_OF_MONTH);

        long periodAsMilliSeconds = end1.getTime() - start1.getTime();
        return (periodAsMilliSeconds / (DAY_MILLISECONDS));
    }


    /*
    * Return date period years
    * years = period as days / 365
    * otherwise return -1;
    * */
    public static long periodAsYears(Date start, Date end) {
        final long days = periodAsDays(start, end);
        return days < 0 ? -1 : days / DAYS_OF_YEAR;
    }

    /*
    * Return date period months
    * months = period as days / 30
    * otherwise return 0;
    * */
    public static long periodAsMonths(Date start, Date end) {
        final long days = periodAsDays(start, end);
        return days < 0 ? 0 : days / DAYS_OF_MONTH;
    }

    /**
     * 计算两个时间之间相差的小时数 ,
     * 精确到秒
     * 忽略 分钟,秒的差异, 如  2014-02-02 01:00:00 与 2014-02-02 02:59:25 之间的相差小时为 1
     *
     * @param time1 Date
     * @param time2 Another Date
     * @return Hours  or -1
     */
    public static long periodAsHours(Date time1, Date time2) {
        if (time1 == null || time2 == null) {
            return -1;
        }
        long periodAsMilliSeconds = time1.getTime() - time2.getTime();
        return Math.abs(periodAsMilliSeconds) / 3600000l;

    }


    /**
     * 返回给定日期所在月的最后一天日期
     *
     * @param date Date
     * @return Last day
     */
    public static Date lastDateOfMonth(Date date) {
        if (date == null) {
            return null;
        }
        Calendar calendar = calendar();
        calendar.setTime(date);
        final int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        return calendar.getTime();
    }

    /**
     * 返回给定日期所在月的第一天日期
     *
     * @param date Date
     * @return First day
     */
    public static Date firstDateOfMonth(Date date) {
        if (date == null) {
            return null;
        }
        Calendar calendar = calendar();
        calendar.setTime(date);
        final int lastDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        return calendar.getTime();
    }

    /**
     * 给指定的日期加 几天时间(正数) 或减几天(负数)
     *
     * @param date Date
     * @param days plus days
     * @return Plussed date
     */
    public static Date plusDays(Date date, int days) {
        if (date == null) {
            return null;
        }
        Calendar calendar = calendar();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, days);
        return calendar.getTime();
    }

    /**
     * 给指定的日期添加 几个月(正数) 或减几个月(负数)
     *
     * @param date   Date
     * @param months plus months
     * @return Plussed date
     */
    public static Date plusMonths(Date date, int months) {
        if (date == null) {
            return null;
        }
        Calendar calendar = calendar();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, months);
        return calendar.getTime();
    }

    /**
     * 获取指定年的最大值 即 12月31号 23:59:59 精确到秒
     *
     * @param year 年
     * @return 最大值
     */
    public static Date getYearMaxDateTime(int year) {
        if (year <= 0) {
            return null;
        }

        String yearAndDateTime = year + "-12-31 23:59:59";
        return DateUtils.getDate(yearAndDateTime, DateUtils.DEFAULT_DATE_TIME_FORMAT);
    }

    /**
     * 获取指定年的最小值 即 1月1号 00:00:00 精确到秒
     *
     * @param year 年
     * @return 最小值
     */
    public static Date getYearMinDateTime(int year) {
        if (year <= 0) {
            return null;
        }

        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        return calendar.getTime();
    }
}